using System;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Dapr.Client;
using EasyDapr.Domain;
using EasyDapr.Infrastructure.App.Dtos;
using EasyDapr.Infrastructure.Attribute;
using EasyDapr.Infrastructure.Response;
using EasyDapr.Infrastructure.Status;
using InventoryService.Application.Requests;
using InventoryService.Domain.Exception;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace InventoryService.Api.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class InventoryController : ControllerBase
    {
        private const string StoreName = "statestore";
        private const string JwtTokenStoreName = "jwt-token-store";

        [Authorize]
        [HttpGet]
        public async Task<ApiResult<InventoryDto>> GetById([FromServices] IMediator mediator, [Required] string id)
        {
            var request = new GetInventoryRequest(id);
            var rsp = await mediator.Send(request);
            return rsp;
        }

        [HttpPost]
        public async Task<ApiResult<bool>> Post(
            [FromServices] IMediator mediator,
            CreateInventoryRequest request,
            CancellationToken cancellationToken)
        {
            return await mediator.Send(request, cancellationToken);
        }

        [HttpGet]
        public IActionResult Status([FromServices] IConfiguration config)
        {
            return new JsonResult(config.BuildAppStatusModel());
        }

        [HttpGet]
        [ApiIgnoreFilter]
        public IActionResult PublishTest([FromServices] DaprClient client)
        {
            client.PublishEventAsync("pubsub", "topic_test", new {UserId = "88421113"});
            return Ok();
        }

        [HttpGet]
        public async Task<IActionResult> StateSet([FromServices] DaprClient client, string key)
        {
            await client.SaveStateAsync(StoreName, key, new {Key = key, Value = DateTime.Now.Ticks});
            return Ok();
        }

        [HttpGet]
        public async Task<IActionResult> StateGet([FromServices] DaprClient client, string key)
        {
            var rsp = await client.GetStateAsync<dynamic>(StoreName, key);
            return new JsonResult(rsp);
        }

        [HttpGet]
        public async Task<IActionResult> JwtStateSet([FromServices] DaprClient client, string key)
        {
            await client.SaveStateAsync(JwtTokenStoreName, key,
                new {Key = key, Value = $"{DateTime.Now.Ticks},{Guid.NewGuid().ToString()}"});
            return Ok();
        }

        [HttpGet]
        public async Task<IActionResult> JwtStateGet([FromServices] DaprClient client, string key)
        {
            var rsp = await client.GetStateAsync<dynamic>(JwtTokenStoreName, key);
            return new JsonResult(rsp);
        }

        [HttpGet]
        public async Task<ApiResult<UserDto>> ServiceCall([FromServices] DaprClient client, string id)
        {
            var result = await client.InvokeMethodAsync<object, ApiResult<UserDto>>(
                "identity-app", "get-user-by-id", new {UserId = id});
            Console.WriteLine(JsonSerializer.Serialize(result));
            return result;
        }
    }
}